package com.niit.musicserve.controller;

import com.alibaba.fastjson.JSONObject;
import com.niit.musicserve.annotation.RequireRole;
import com.niit.musicserve.entity.Admin;
import com.niit.musicserve.entity.Consumer;
import com.niit.musicserve.entity.Song;
import com.niit.musicserve.service.SongService;
import com.niit.musicserve.utils.Const;
import com.niit.musicserve.utils.Result;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/song")
public class SongController {
	
	@Autowired
	public SongService songService;
	
	/**
	 * 添加歌曲
	 * @param songName 歌曲名称
	 * @param singerId 歌手ID
	 * @param songAlbum 专辑名称
	 * @param songLyr 歌词
	 * @param mpFile 歌曲文件
	 * @return 操作结果
	 */
	@RequestMapping(value = "/add", method = RequestMethod.POST)
	@RequireRole({"admin","consumer"})
	public Result<String> addSong(
		@RequestParam("songName") String songName,
		@RequestParam("singerId") Integer singerId,
		@RequestParam(value = "songAlbum", required = false) String songAlbum,
		@RequestParam(value = "songLyr", required = false) String songLyr,
		@RequestParam("file") MultipartFile mpFile) {
		
		try{
			// 参数校验
			if (singerId == null) {
				return Result.error("歌手ID不能为空");
			}
			if (songName == null || songName.trim().isEmpty()) {
				return Result.error("歌曲名称不能为空");
			}
			
			//判断文件是否存在
			if(mpFile.isEmpty()){
				return Result.error("文件不能为空");
			}
			
			//统一设置保存到数据困中的文件名，为避免重复，这里的文件名格式统一设置为当前时间+原文件名
			String fileName = System.currentTimeMillis() + mpFile.getOriginalFilename();
			//获取文件的目的路径
			String filePath = System.getProperty("user.dir") + "/res/song/";
			//判断文件路径是否存在，不存在则创建
			File file1 = new File(filePath);
			if(!file1.exists()){
				// 检查父目录是否存在，如果不存在则创建
				File parentDir = file1.getParentFile();
				if (parentDir != null && !parentDir.exists()) {
					if (!parentDir.mkdirs()) {
						return Result.error("无法创建目录: " + parentDir.getAbsolutePath());
					}
				}
				// 创建目标目录
				if (!file1.mkdirs()) {
					return Result.error("无法创建目录: " + file1.getAbsolutePath());
				}
			}
			//文件实际存储路径
			File dest = new File(filePath+System.getProperty("file.separator")+fileName);
			//设置文件上传的目的路径即存储到数据库里文件的相对位置
			String storeUrlPath = "res/song/" + fileName;
			//存储文件
			
			Date time = new Date();
			mpFile.transferTo(dest);
			
			int duration = getAudioDuration(storeUrlPath);
			
			// 处理可选参数
			Song song = new Song();
			song.setSongName(songName.trim());
			song.setSingerId(singerId);
			song.setSongAlbum(songAlbum != null ? songAlbum.trim() : "");
			song.setSongPic("");
			song.setSongLyr(songLyr != null ? songLyr.trim() : "");
			song.setSongUrl(storeUrlPath);
			song.setDuration(duration);
			
			song.setCreateUser("admin");
			song.setUpdateUser("admin");
			song.setCreateTime(time);
			song.setUpdateTime(time);
			
			int flag = songService.insertSong(song);
			
			if(flag >0){
				return Result.success("歌曲添加成功",null);
			}
			
			return Result.error("歌曲添加失败");
		}
		catch (IOException e) {
			return Result.error("文件不存在: " + e.getMessage());
		}
		catch (Exception e){
			e.printStackTrace(); // 打印堆栈信息便于调试
			return Result.error("添加失败: " + e.getMessage());
		}
	}
	
	/**
	 * 删除歌曲
	 * @param request 前端请求
	 * @return 操作结果
	 */
	@RequestMapping(value = "/delete", method = RequestMethod.GET)
	@RequireRole({"admin","consumer"})
	public Result<String> deleteSong(HttpServletRequest request) {
		
		try{
			String songId = request.getParameter("songId").trim();
			
			int flag = songService.deleteSongById(Integer.parseInt(songId));
			
			if(flag > 0){
				
				return Result.success("删除成功",null);
				
			}else {
				
				return Result.error("删除失败");
			}
		}
		catch (Exception e) {
			
			return Result.error("删除失败");
		}
	}
	
	/**
	 * 修改歌曲
	 * @param song 前端数据
	 * @return 操作结果
	 */
	@RequestMapping(value = "/update", method = RequestMethod.POST)
	@RequireRole({"admin","consumer"})
	public Result<String> updateSong(@RequestBody Song song) {
		
		try{
			
			if(song.getSongName() == null || song.getSongName().trim().isEmpty()){
				return Result.error("歌曲名称不能为空");
			}
			
			if(song.getSingerId() == null){
				return Result.error("歌手ID不能为空");
			}
			
			song.setSongName(song.getSongName().trim());
			song.setSingerId(song.getSingerId());
			song.setSongAlbum(song.getSongAlbum().trim());
			song.setSongLyr(song.getSongLyr().trim());
			Date updateTime = new Date();
			
			int result = songService.updateSongById(song);
			if(result > 0){
				
				return Result.success("修改成功",null);
			}else {
				
				return Result.error("修改失败");
			}
		}
		catch (Exception e) {
			
			return Result.error("修改失败" + e.getMessage());
		}
	}
	
	/**
	 * 查询所有歌曲
	 * @return 歌曲列表
	 */
	@RequestMapping(value = "/allSong", method = RequestMethod.GET)
	public Result<List<Song>> allSong() {
		
		return Result.success(songService.allSong());
	}
	
	/**
	 * 分页查询歌曲列表
	 * @param pageNum 页码
	 * @param pageSize 每页大小
	 * @return 分页结果
	 */
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public Result<JSONObject> listSongs(
		@RequestParam(defaultValue = "1") Integer pageNum,
		@RequestParam(defaultValue = "10") Integer pageSize) {
		
		try {
			// 获取所有歌曲（含歌手名）
			List<Song> allSongs = songService.allSongWithSinger();
			
			// 计算分页数据
			int total = allSongs.size();
			int startIndex = (pageNum - 1) * pageSize;
			int endIndex = Math.min(startIndex + pageSize, total);
			
			// 获取当前页的歌曲列表
			List<Song> pageSongs = allSongs.subList(startIndex, endIndex);
			
			// 构造返回结果
			JSONObject result = new JSONObject();
			result.put("list", pageSongs);
			result.put("total", total);
			result.put("pageNum", pageNum);
			result.put("pageSize", pageSize);
			result.put("pages", (int) Math.ceil((double) total / pageSize));
			
			return Result.success("查询成功", result);
		} catch (Exception e) {
			e.printStackTrace();
			return Result.error("查询失败: " + e.getMessage());
		}
	}
	
	/**
	 * 搜索歌曲
	 * @param keywords 搜索关键词
	 * @param pageNum 页码
	 * @param pageSize 每页大小
	 * @return 搜索结果
	 */
	@RequestMapping(value = "/search", method = RequestMethod.GET)
	public Result<JSONObject> searchSongs(
		@RequestParam(required = false) String keywords,
		@RequestParam(defaultValue = "1") Integer pageNum,
		@RequestParam(defaultValue = "10") Integer pageSize) {
		
		try {
			List<Song> songs;
			
			if (keywords != null && !keywords.trim().isEmpty()) {
				// 如果有关键词，进行模糊搜索
				songs = songService.likeSongByName(keywords.trim());
			} else {
				// 如果没有关键词，返回所有歌曲
				songs = songService.allSong();
			}
			
			// 计算分页数据
			int total = songs.size();
			int startIndex = (pageNum - 1) * pageSize;
			int endIndex = Math.min(startIndex + pageSize, total);
			
			// 获取当前页的歌曲列表
			List<Song> pageSongs = startIndex < total ? songs.subList(startIndex, endIndex) : List.of();
			
			// 构造返回结果
			JSONObject result = new JSONObject();
			result.put("list", pageSongs);
			result.put("total", total);
			result.put("pageNum", pageNum);
			result.put("pageSize", pageSize);
			result.put("pages", total > 0 ? (int) Math.ceil((double) total / pageSize) : 0);
			
			return Result.success("查询成功", result);
		} catch (Exception e) {
			e.printStackTrace();
			return Result.error("查询失败: " + e.getMessage());
		}
	}
	
	@RequestMapping(value = "/test", method = RequestMethod.GET)
	public Result<String> testApi() {
		return Result.success("API接口工作正常");
	}
	
	/**
	 * 根据歌曲id查询歌曲
	 * @return 歌曲列表
	 */
	@RequestMapping(value = "/songOfId", method = RequestMethod.GET)
	public Result<Song> songOfId(HttpServletRequest request) {
		try {
			String songId = request.getParameter("songId");
			if (songId == null || songId.trim().isEmpty()) {
				return Result.error("歌曲ID不能为空");
			}
			
			Song song = songService.songById(Integer.parseInt(songId.trim()));
			if (song != null) {
				return Result.success("查询成功", song);
			} else {
				return Result.error("歌曲不存在");
			}
		} catch (Exception e) {
			e.printStackTrace();
			return Result.error("查询失败: " + e.getMessage());
		}
	}
	
	/**
	 * 根据歌曲名模糊查询歌曲
	 * @param request 前端数据
	 * @return 歌曲列表
	 */
	@RequestMapping(value = "/likeSongOfName", method = RequestMethod.GET)
	public Result<List<Song>> likeSongOfName(HttpServletRequest request){
		
		String songName = request.getParameter("songName").trim();
		
		return Result.success(songService.likeSongByName(songName));
	}
	
	/**
	 * 根据歌曲名精准查询歌曲
	 * @param request 前端数据
	 * @return 歌曲列表
	 */
	@RequestMapping(value = "/songOfName", method = RequestMethod.GET)
	public Result<List<Song>> songOfName(HttpServletRequest request){
		
		String songName = request.getParameter("songName").trim();
		
		return Result.success(songService.songByName(songName));
	}
	
	/**
	 * 根据歌手id查询歌曲
	 * @param request 前端数据
	 * @return 歌曲列表
	 */
	@RequestMapping(value = "/songOfSingerId", method = RequestMethod.GET)
	public Result<List<Song>> songOfSingerId(HttpServletRequest request){
		
		String singerId = request.getParameter("singerId").trim();
		
		return Result.success(songService.songBySingerId(Integer.parseInt(singerId)));
	}
	
	@RequestMapping(value = "/numberOfSong", method = RequestMethod.GET)
	public Result<Integer> numberOfSong(){
		
		return Result.success(songService.numberOfSong());
	}
	
	/**
	 * 上传歌曲图片
	 * @param picFile 歌曲图片
	 * @param id 歌曲id
	 * @return 操作结果
	 */
	@RequireRole({ "admin", "consumer"})
	@RequestMapping(value = "/songOfPic", method = RequestMethod.POST)
	public Result<String> updateSongOfPic(
		@RequestParam("file") MultipartFile picFile,
		@RequestParam("id") int id)
	{
		// 保持原有实现不变
		if(picFile.isEmpty()){
			return Result.error("文件不存在");
		}
		
		String fileName = System.currentTimeMillis() + picFile.getOriginalFilename();
		
		String filePath = System.getProperty("user.dir")+ "/res/img/songPic";
		
		File file1 = new File(filePath);
		if(!file1.exists()){
			file1.mkdirs();
		}
		
		File dest = new File(filePath + System.getProperty("file.separator") + fileName);
		
		String storeUrlPath = "/img/songPic/" + fileName;
		
		try {
			picFile.transferTo(dest);
			
			Song song = new Song();
			song.setSongId(id);
			song.setSongPic(storeUrlPath);
			int result = songService.updateSongById(song);
			
			if(result > 0){
				return Result.success("更新成功",null);
			}
			
			return Result.error("更新失败");
		}
		catch (IOException e) {
			return Result.error("更新失败" + e.getMessage());
		}
	}
	
	/**
	 * 获取音频文件时长（秒）
	 * @param songUrl 音频文件路径
	 * @return 时长（秒）
	 */
	private int getAudioDuration(String songUrl) {
		if(songUrl == null || songUrl.isEmpty()){
			return 180;
		}
		
		try {
			String fullPath = System.getProperty("user.dir") + "/" + songUrl;
			File audioFile = new File(fullPath);
			if(!audioFile.exists()){
				return 180;
			}
			
			// 使用JavaSound API获取音频时长
			java.io.FileInputStream fis = new java.io.FileInputStream(audioFile);
			javazoom.jl.player.Player player = new javazoom.jl.player.Player(fis);
			
			// 获取音频文件头信息
			javazoom.jl.decoder.Bitstream bitstream = new javazoom.jl.decoder.Bitstream(fis);
			javazoom.jl.decoder.Header header = bitstream.readFrame();
			
			if (header != null) {
				// 计算时长（秒）
				int bitrate = header.bitrate(); // 转换为bps
				long fileSize = audioFile.length(); // 文件大小（字节）
				int durationSeconds = (int) (fileSize * 8 / bitrate); // 时长（秒）
				return Math.max(1, durationSeconds); // 避免时长小于1秒
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		// 如果无法计算，默认返回180秒（3分钟）
		return 180;
	}
}
